package cmd

import (
	"embed"
	"fmt"
	"os"
	"path/filepath"

	"gitee.com/xuender/oils/gui"
	"gitee.com/xuender/toolkit/format"
	"gitee.com/xuender/toolkit/hash"
	"gitee.com/xuender/toolkit/nets"
	"gitee.com/xuender/toolkit/utils"
	homedir "github.com/mitchellh/go-homedir"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var (
	WWW     *embed.FS
	cfgFile string
	// Version 版本号.
	Version = "v1.0.0"
	// BuildTime 编译时间.
	BuildTime = "0000-00-00"
	// GitCommit 提交.
	GitCommit = "00000000"
)

var rootCmd = &cobra.Command{
	Use:   "toolkit",
	Short: "工具箱",
	Long: fmt.Sprintf(`一些常用命令组成的工具箱

Version: %s
BuildTime: %s
GitCommit: %s`, Version, BuildTime, GitCommit),
	Run: func(cmd *cobra.Command, args []string) {
		w, _ := cmd.Flags().GetInt("width")
		h, _ := cmd.Flags().GetInt("height")
		s := gui.NewGUI()
		defer s.Close()

		s.FS("www", *WWW)

		s.Bind("get", viper.Get)
		s.Bind("set", utils.Set)
		s.Bind("readFile", utils.ReadFile)

		s.Bind("now", format.Now)
		s.Bind("hash", hash.Hash)
		s.Bind("fileHash", hash.FileHash)

		s.Bind("ping", nets.Ping)
		s.Bind("pingCall", nets.PingCall)

		s.Bind("folder", utils.Folder)

		_ = s.Open("/", "toolkit", w, h)
		s.Run()
	},
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	cobra.CheckErr(rootCmd.Execute())
}

// nolint: gochecknoinits
func init() {
	cobra.OnInitialize(initConfig)

	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "配置文件 (默认 $HOME/.toolkit.toml)")
	rootCmd.Flags().IntP("width", "", 1000, "窗口宽度")
	rootCmd.Flags().IntP("height", "", 820, "窗口高度")
}

func initConfig() {
	if cfgFile != "" {
		viper.SetConfigFile(cfgFile)
	} else {
		home, err := homedir.Dir()
		cobra.CheckErr(err)

		viper.AddConfigPath(home)
		viper.SetConfigType("toml")
		viper.SetConfigName(".toolkit")
		cfgFile = filepath.Join(home, ".toolkit.toml")
	}

	viper.AutomaticEnv()

	if err := viper.ReadInConfig(); err == nil {
		fmt.Fprintln(os.Stderr, "加载配置文件: ", viper.ConfigFileUsed())
	} else {
		_ = viper.WriteConfigAs(cfgFile)
	}
}
